//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include "Winhack.h"
#include <elasys_server.h>
#include "CDirEnumerator.h"
#include "aura.h"

#define FIXME Aura_printf("[FixMe]<%s> Not Implemented.\n", __FUNCTION__);

#define ERROR_NO_MORE_FILES    18

UInt32 CDirEnumerator::AddRef()
{
    UInt32 nRef = m_cRef.Increment();
    return nRef;
}

UInt32 CDirEnumerator::Release()
{
    UInt32 nRef = m_cRef.Decrement();

    if (0 == nRef) {
        delete this;
    }
    return nRef;
}

ECode CDirEnumerator::Aggregate(
    AggregateType type, PInterface pObj)
{
    FIXME;
    return E_NOT_IMPLEMENTED;
}

ECode CDirEnumerator::GetDomain(
    IInterface **ppObj)
{
    FIXME;
    return E_NOT_IMPLEMENTED;
}

PInterface CDirEnumerator::Probe(REIID riid)
{
    if (EIID_IInterface == riid) {
        return (IInterface *)(IWStringEnumerator *)this;
    }
    else if (EIID_IWStringEnumerator == riid) {
        return (IWStringEnumerator *)this;
    }
    else if (EIID_CLASS_INFO == riid) {
        return (IInterface *)&ECLSID_CKtfsDirStrEnumerator;
    }
    else if (EIID_INTERFACE_INFO == riid) {
        return (IInterface *)&EIID_IWStringEnumerator;
    }

    return NULL;
}

CDirEnumerator::CDirEnumerator()
{
    m_hFile = INVALID_HANDLE_VALUE;
    m_bMove = FALSE;
    m_bReset = TRUE;
    m_pPathName = NULL;
    memset(m_FileName, 0, sizeof(m_FileName));
}

ECode CDirEnumerator::Initialize(wchar_t *pPathName)
{
    m_pPathName = (wchar_t *)malloc(sizeof(wchar_t *) * (wcslen(pPathName) + 1));
    if (NULL == m_pPathName) {
        return E_OUT_OF_MEMORY;
    }
    wcscpy(m_pPathName, pPathName);
    return NOERROR;
}

CDirEnumerator::~CDirEnumerator()
{
    if (NULL != m_pPathName) {
        free (m_pPathName);
    }

    if (INVALID_HANDLE_VALUE != m_hFile) {
        FindClose(m_hFile);
    }
}

ECode CDirEnumerator::Current(
    /* [out] */ WStringBuf * pPsa)
{
    if (m_bReset || L'\0' == m_FileName[0]) {
        return E_INVALID_OPERATION;
    }

    if (NULL == pPsa 
      || pPsa->IsNull()
      || pPsa->GetCapacity() < (Int32)wcslen(m_FileName)) {
        return E_INVALID_ARGUMENT;
    }

    pPsa->Copy(m_FileName);
    return NOERROR;
}

ECode CDirEnumerator::MoveNext()
{
    WIN32_FIND_DATAW findFileData;
    Int32 lastError = 0;

    m_bReset = FALSE;
    memset(&findFileData, 0, sizeof(WIN32_FIND_DATAW));

    if (!m_bMove) {
        m_hFile = FindFirstFileW(m_pPathName, &findFileData);
        if (INVALID_HANDLE_VALUE == m_hFile) {
            lastError = GetLastError();
            if (ERROR_NO_MORE_FILES == lastError) {
                m_FileName[0] = L'.';
                m_FileName[1] = L'\0';
                m_bMove = TRUE;
                return NOERROR;
            }
            return E_FILE_NOT_FOUND;
        }
        m_bMove = TRUE;
    } else {
        if (INVALID_HANDLE_VALUE == m_hFile
          ||!FindNextFileW(m_hFile, &findFileData)) {
            m_FileName[0] = L'\0';
            return E_FS_NO_SUCH_FILE;
        } 
    }

    wcscpy(m_FileName, findFileData.cFileName);
    return NOERROR;
}

ECode CDirEnumerator::Reset()
{
    m_bReset = TRUE;
    m_bMove = FALSE;
    FindClose(m_hFile);
    m_hFile = INVALID_HANDLE_VALUE;
    return NOERROR;
}

